﻿//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Logging Application Block
//===============================================================================
// License: http://www.codeplex.com/entlibcontrib/Project/License.aspx
// Author: Randy
//===============================================================================

using System.Text;
using System.IO;

namespace EntLibContrib.Logging.TraceListeners
{
	/// <summary>
	/// Tally Keeping File stream writer
	/// </summary>
	public sealed class TallyKeepingFileStreamWriter : StreamWriter
	{
		#region Fields
		private long tally;
		#endregion

		#region Properties
		/// <summary>
		/// Gets the tally.
		/// </summary>
		/// <value>The tally.</value>
		public long Tally
		{
			get { return tally; }
		}
		#endregion

		#region Construction
		/// <summary>
		/// Initializes a new instance of the <see cref="TallyKeepingFileStreamWriter"/> class.
		/// </summary>
		/// <param name="stream">The stream.</param>
		public TallyKeepingFileStreamWriter(FileStream stream)
			: base(stream)
		{
			tally = stream.Length;
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="TallyKeepingFileStreamWriter"/> class.
		/// </summary>
		/// <param name="stream">The stream.</param>
		/// <param name="encoding">The encoding.</param>
		public TallyKeepingFileStreamWriter(FileStream stream, Encoding encoding)
			: base(stream, encoding)
		{
			tally = stream.Length;
		}
		#endregion

		#region Public Methods
		/// <summary>
		/// Writes a character to the stream.
		/// </summary>
		/// <param name="value">The character to write to the text stream.</param>
		/// <exception cref="T:System.IO.IOException">
		/// An I/O error occurs.
		/// </exception>
		/// <exception cref="T:System.ObjectDisposedException">
		/// 	<see cref="P:System.IO.StreamWriter.AutoFlush"/> is true or the <see cref="T:System.IO.StreamWriter"/> buffer is full, and current writer is closed.
		/// </exception>
		/// <exception cref="T:System.NotSupportedException">
		/// 	<see cref="P:System.IO.StreamWriter.AutoFlush"/> is true or the <see cref="T:System.IO.StreamWriter"/> buffer is full, and the contents of the buffer cannot be written to the underlying fixed size stream because the <see cref="T:System.IO.StreamWriter"/> is at the end the stream.
		/// </exception>
		public override void Write(char value)
		{
			base.Write(value);
			this.tally += this.Encoding.GetByteCount(new char[] { value });
		}

		/// <summary>
		/// Writes a character array to the stream.
		/// </summary>
		/// <param name="buffer">A character array containing the data to write. If <paramref name="buffer"/> is null, nothing is written.</param>
		/// <exception cref="T:System.IO.IOException">
		/// An I/O error occurs.
		/// </exception>
		/// <exception cref="T:System.ObjectDisposedException">
		/// 	<see cref="P:System.IO.StreamWriter.AutoFlush"/> is true or the <see cref="T:System.IO.StreamWriter"/> buffer is full, and current writer is closed.
		/// </exception>
		/// <exception cref="T:System.NotSupportedException">
		/// 	<see cref="P:System.IO.StreamWriter.AutoFlush"/> is true or the <see cref="T:System.IO.StreamWriter"/> buffer is full, and the contents of the buffer cannot be written to the underlying fixed size stream because the <see cref="T:System.IO.StreamWriter"/> is at the end the stream.
		/// </exception>
		public override void Write(char[] buffer)
		{
			base.Write(buffer);
			this.tally += this.Encoding.GetByteCount(buffer);
		}

		/// <summary>
		/// Writes a subarray of characters to the stream.
		/// </summary>
		/// <param name="buffer">A character array containing the data to write.</param>
		/// <param name="index">The index into <paramref name="buffer"/> at which to begin writing.</param>
		/// <param name="count">The number of characters to read from <paramref name="buffer"/>.</param>
		/// <exception cref="T:System.ArgumentNullException">
		/// 	<paramref name="buffer"/> is null.
		/// </exception>
		/// <exception cref="T:System.ArgumentException">
		/// The buffer length minus <paramref name="index"/> is less than <paramref name="count"/>.
		/// </exception>
		/// <exception cref="T:System.ArgumentOutOfRangeException">
		/// 	<paramref name="index"/> or <paramref name="count"/> is negative.
		/// </exception>
		/// <exception cref="T:System.IO.IOException">
		/// An I/O error occurs.
		/// </exception>
		/// <exception cref="T:System.ObjectDisposedException">
		/// 	<see cref="P:System.IO.StreamWriter.AutoFlush"/> is true or the <see cref="T:System.IO.StreamWriter"/> buffer is full, and current writer is closed.
		/// </exception>
		/// <exception cref="T:System.NotSupportedException">
		/// 	<see cref="P:System.IO.StreamWriter.AutoFlush"/> is true or the <see cref="T:System.IO.StreamWriter"/> buffer is full, and the contents of the buffer cannot be written to the underlying fixed size stream because the <see cref="T:System.IO.StreamWriter"/> is at the end the stream.
		/// </exception>
		public override void Write(char[] buffer, int index, int count)
		{
			base.Write(buffer, index, count);
			this.tally += this.Encoding.GetByteCount(buffer, index, count);
		}

		/// <summary>
		/// Writes a string to the stream.
		/// </summary>
		/// <param name="value">The string to write to the stream. If <paramref name="value"/> is null, nothing is written.</param>
		/// <exception cref="T:System.ObjectDisposedException">
		/// 	<see cref="P:System.IO.StreamWriter.AutoFlush"/> is true or the <see cref="T:System.IO.StreamWriter"/> buffer is full, and current writer is closed.
		/// </exception>
		/// <exception cref="T:System.NotSupportedException">
		/// 	<see cref="P:System.IO.StreamWriter.AutoFlush"/> is true or the <see cref="T:System.IO.StreamWriter"/> buffer is full, and the contents of the buffer cannot be written to the underlying fixed size stream because the <see cref="T:System.IO.StreamWriter"/> is at the end the stream.
		/// </exception>
		/// <exception cref="T:System.IO.IOException">
		/// An I/O error occurs.
		/// </exception>
		public override void Write(string value)
		{
			base.Write(value);
			this.tally += this.Encoding.GetByteCount(value);
		}
		#endregion
	}
}
